/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.elkastud.model;

/**
 * Class contains implementation of sample nucleobase resemblance.
 * Resemblance of two nucleobases is given in resemblance matrix.
 * Resemblance of three nucleobases is calculated as sum of all (3) pairs
 * @author Jakub Skierbiszewski
 */
public class NucleobaseSampleResemblance implements INucleobaseResemblance
{
	/** Array containg resemblance data */
	private short[][] mResemblanceArray =
	{
		////// A | G | C | T | - //
//		/*A*/{10, -1, -3, -4, -5},
//		/*G*/{-1,  7, -5, -3, -5},
//		/*C*/{-3, -5,  9,  0, -5},
//		/*T*/{-4, -3,  0,  8, -5},
//		/*-*/{-5, -5, -5, -5,  0}
//		////// A | G | C | T | - //
//		/*A*/ {1, -3, -3, -3, -5},
//		/*G*/{-3,  1, -3, -3, -5},
//		/*C*/{-3, -3,  1,  0, -5},
//		/*T*/{-3, -3,  0,  1, -5},
//		/*-*/{-5, -5, -5, -5,  0}
		////// A | G | C | T | - //
		/*A*/{ 1, -1, -1, -1, -2},
		/*G*/{-1,  1, -1, -1, -2},
		/*C*/{-1, -1,  1,  0, -2},
		/*T*/{-1, -1,  0,  1, -2},
		/*-*/{-2, -2, -2, -2,  0}
	};

	/** Gap penalty value */
	private static final short GAP_PENALTY = -5;

	/**
	 * Value of resemblance from array representation
	 * @param a
	 * @param b
	 * @return value of resemblance
	 */
	@Override
	public short getResemblance(Nucleobase a, Nucleobase b)
	{
		return mResemblanceArray[getIndexForNucleobase(a)][getIndexForNucleobase(b)];
	}

	/**
	 * Returns sum of resemblance value for all pairs: (a,b) (b,c) (a,c)
	 * @param a
	 * @param b
	 * @param c
	 * @return value of resemblance
	 */
	@Override
	public short getResemblance(Nucleobase a, Nucleobase b, Nucleobase c)
	{
		return (short) (
				mResemblanceArray[getIndexForNucleobase(a)][getIndexForNucleobase(b)] +
				mResemblanceArray[getIndexForNucleobase(b)][getIndexForNucleobase(c)] +
				mResemblanceArray[getIndexForNucleobase(a)][getIndexForNucleobase(c)]);
	}

	/**
	 * Converts nucleobase to resemblance array index
	 * @param n
	 * @return index of nucleobase
	 */
	private short getIndexForNucleobase(Nucleobase n)
	{
		if(n.getNucleobaseCode()=='A')
			return 0;

		else if(n.getNucleobaseCode() == 'G')
			return 1;

		else if(n.getNucleobaseCode()=='C')
			return 2;

		else if(n.getNucleobaseCode()=='T')
			return 3;
		else
			return 4;
	}

	/**
	 * @return gap penalty
	 */
	public short getGapPenalty()
	{
		return GAP_PENALTY;
	}

}
